package org.univali.cg.view;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.univali.cg.bo.Linha2D;
import org.univali.cg.bo.Matriz;
import org.univali.cg.bo.Nave2D;
import org.univali.cg.bo.ObjetoGrafico;
import org.univali.cg.bo.Ponto2D;
import org.univali.cg.bo.Window;




public class JavaViewport extends JPanel implements KeyListener{

	private static final long serialVersionUID = -2053389789154950777L;
	private Graphics2D g2d;
	private Window window;
	private Ponto2D min, max;
	ArrayList<ObjetoGrafico> objetos;

	public JavaViewport(float largura, float altura, Window w) {
		this.setFocusable(true);
		this.addKeyListener(this);
		this.setPreferredSize(new Dimension((int)largura,(int)altura));
		
		this.window = w;
		this.min = new Ponto2D(0,0);
		this.max = new Ponto2D(largura,altura);
		objetos = new ArrayList<ObjetoGrafico>();
		
		Linha2D linha = new Linha2D(new Ponto2D(-100,-100), new Ponto2D(100,100));
		Nave2D nave = new Nave2D(new Ponto2D(0,0));
		
		objetos.add(linha);
		objetos.add(nave);
	}

	public void paintComponent(Graphics g) {
	    clear(g);
	    Graphics2D g2d = (Graphics2D)g;
	    g2d.setColor(new Color(1.0f,0.0f,0.0f));
	    this.g2d = g2d;

	    for (ObjetoGrafico obj: objetos){
	    	obj.desenhe(this.window, this);
	    }
	    
	    this.g2d = null;
	  }

	protected void clear(Graphics g) {
		super.paintComponent(g);
	}
	  
	public static Ponto2D transformada(Ponto2D p, Window w, JavaViewport vp){
		double larguraViewPort = vp.getWidth();
		double larguraJanela = w.getMax().getX() - w.getMin().getX();
		
		double alturaViewPort = vp.getHeight();
		double alturaJanela = w.getMax().getY() - w.getMin().getY();
		
		
		double xTransformado = 
			( ( p.getX() - w.getMin().getX() ) / larguraJanela ) * larguraViewPort;
		double yTransformado = 
			( 1 - ( p.getY() - w.getMin().getY() ) / alturaJanela ) * alturaViewPort;
		return new Ponto2D(
				xTransformado, 
				yTransformado);
	}

	
	
	public void desenhaLinha(Ponto2D p1, Ponto2D p2){
		g2d.draw(new Line2D.Double(new Point2D.Double(p1.getX(),p1.getY()), new Point2D.Double(p2.getX(),p2.getY())));
	}
	
	

	public void desenhaPoligono(Ponto2D... pontos){
		this.desenhaPoligono(Arrays.asList(pontos));
	}

	
	public void desenhaPoligono(List<Ponto2D> pontos){
		GeneralPath poligono = new GeneralPath();
		Iterator<Ponto2D> iteratorPontos = pontos.iterator();
		if(iteratorPontos.hasNext()){
			Ponto2D pontoAtual = iteratorPontos.next();
			poligono.moveTo(pontoAtual.getX(), pontoAtual.getY());
			while(iteratorPontos.hasNext()){
				pontoAtual = iteratorPontos.next();
				poligono.lineTo(pontoAtual.getX(), pontoAtual.getY());
				
			}
			poligono.closePath();
			g2d.setColor(Color.GREEN);
			g2d.fill(poligono);
		}
	}

	public static void main(String[] args) {
		float largura = 800, altura = 600;
		Window w = new Window(new Ponto2D(-100,-100), new Ponto2D(100,100));
		JavaViewport content = new JavaViewport(largura, altura, w);

		JFrame frame = new JFrame("JavaCG");
		frame.setLayout(new BorderLayout());

		content.setBackground(new Color(1.0f,1.0f,1.0f));
		frame.setMinimumSize(new Dimension((int)largura, (int)altura));
		frame.setContentPane(content);
		frame.setVisible(true); 
		frame.pack();

		testaMatrizes();
	}
	  
	public static void testaMatrizes(){		
		Matriz a = new Matriz(1,3);
		Matriz b = new Matriz(3,1);
		for (int i = 0; i < 3; i++){
			a.set(0, i, 1);
			b.set(i, 0, 2);
		}
		Matriz c = a.vezes(b);
		a.print();
		System.out.println();
		b.print();
		System.out.println();
		c.print();
		
	}

	public Ponto2D getMin() {
		return min;
	}

	public Ponto2D getMax() {
		return max;
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		switch (e.getKeyCode()){
		case KeyEvent.VK_UP: 
			break;
		case KeyEvent.VK_DOWN: 
			break;
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	}